<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Skit\Ctl;

use Srv\Apps\Proto\DTO\Skit\SkitTplRmdAddDTO;
use Srv\Apps\Proto\DTO\Skit\SkitTplRmdEditDTO;
use Srv\Apps\Proto\DTO\Skit\SkitTplRmdListDTO;
use Srv\Apps\Proto\Enum\PlatformEnum;
use Srv\Apps\Proto\Enum\YesOrNoEnum;
use Srv\Apps\Proto\VO\Skit\SkitTplRmdListVO;
use Srv\Apps\Proto\VO\Skit\SkitTplRmdVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Common\CommJson;
use Srv\Libs\Common\CommTime;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;

final class SkitTplRmdCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write

    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param int $tprdId
     * @return array
     * getSkitTplRmdSrc
     */
    public function getSkitTplRmdSrc(int $tprdId):array
    {
        if($tprdId < 1) return [];
        $isFail     = false;
        $info       = $this->DbAuto->getDataOne('SELECT tprd_id, tprd_platform, tprd_name, skio_ids, tprd_default, tprd_create_time, tprd_update_time FROM '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').' WHERE tprd_id='.$tprdId.' AND tprd_delete=0', $isFail);
        if($isFail || !isset($info['tprd_id'])) return [];
        return $info;
    }

    /**
     * @param array $tprdIdList
     * @return array
     * getSkitTplRmdSrcBatch
     */
    public function getSkitTplRmdSrcBatch(array $tprdIdList):array
    {
        if(count($tprdIdList) < 1) return [];
        $isFail     = false;
        $list       = $this->DbAuto->getData('SELECT tprd_id, tprd_platform, tprd_name, skio_ids, tprd_default, tprd_create_time, tprd_update_time FROM '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').' WHERE tprd_id IN('.implode(',', $tprdIdList).') AND tprd_delete=0', $isFail);
        if($isFail || count($list) < 1) return [];
        $listData   = [];
        foreach ($list as $item){
            $tprdIdItem             = intval($item['tprd_id']??0);
            if($tprdIdItem < 1) continue;
            $listData[$tprdIdItem]  = $item;
        }
        return $listData;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return SkitTplRmdListVO|null
     * getSkitTplRmdList
     */
    public function getSkitTplRmdList(Page $Page, array $whereData): ?SkitTplRmdListVO
    {
        $limitString            = $Page->getLimitString();
        $whereString            = ' WHERE tprd_delete=0 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case SkitTplRmdListDTO::_tprdId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'tprd_id='. intval($val);
                    break;
                case SkitTplRmdListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'tprd_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case SkitTplRmdListDTO::_default:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'tprd_default='. intval($val);
                    break;
                case SkitTplRmdListDTO::_platform:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'tprd_platform='. intval($val);
                    break;
            }
        }
        $isFail                 = false;
        $sql                    = 'SELECT SQL_CALC_FOUND_ROWS tprd_id, tprd_platform, tprd_name, skio_ids, tprd_default, tprd_create_time, tprd_update_time FROM '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').$whereString.' ORDER BY tprd_id DESC '.$limitString;
        $list                   = $this->DbAuto->getData($sql, $isFail);
        $totalNum               = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $SkitTplRmdVOList       = [];
        if(CommArray::isForeach($list))foreach($list as $info){
            $tprdIdItem         = intval($info['tprd_id']);
            if($tprdIdItem < 1) continue;
            $SkitTplRmdVO       = $this->getSkitTplRmdVO($info);
            if(!($SkitTplRmdVO instanceof SkitTplRmdVO)) continue;
            $SkitTplRmdVOList[] = $SkitTplRmdVO;
        }
        $SkitTplRmdListVO       = new SkitTplRmdListVO();
        $SkitTplRmdListVO->setList($SkitTplRmdVOList);
        $SkitTplRmdListVO->setPage($Page->getPageVO($totalNum));
        return $SkitTplRmdListVO;
    }

    /**
     * @param int $tprdId
     * @return SkitTplRmdVO|null
     * getSkitTplRmdInfo
     */
    public function getSkitTplRmdInfo(int $tprdId):?SkitTplRmdVO
    {
        $theaterSrc     = $this->getSkitTplRmdSrc($tprdId);
        if(!isset($theaterSrc['tprd_id'])) return null;
        return $this->getSkitTplRmdVO($theaterSrc);
    }


    /**
     * @param array $tprdIdList
     * @return array
     * getSkitInfoBatch
     */
    public function getSkitTplRmdInfoBatch(array $tprdIdList):array
    {
        $skitTplRmdList = $this->getSkitTplRmdSrcBatch($tprdIdList);
        $listData       = [];
        if(CommArray::isForeach($skitTplRmdList))foreach ($skitTplRmdList as $item){
            $tprdIdItem             = intval($item['tprd_id']??0);
            if($tprdIdItem < 1) continue;
            $listData[$tprdIdItem]  = $this->getSkitTplRmdVO($item);
        }
        return $listData;
    }

    /**
     * @param array $info
     * @return SkitTplRmdVO|null
     * getSkitTplRmdVO
     */
    public function getSkitTplRmdVO(array $info):?SkitTplRmdVO
    {
        $tprdId             = intval($info['tprd_id']??0);
        if($tprdId < 1) return null;
        $SkitTplRmdVO       = new SkitTplRmdVO();
        $SkitTplRmdVO->setTprdId($tprdId);
        $SkitTplRmdVO->setName(trim($info['tprd_name']));
        $skioIdList         = CommJson::decodeArray($info['skio_ids']);
        $skitInfoVOListNew  = [];
        $SkitInfoVOList     = SkitInfoCtl::tag()->getSkitInfoBatch($skioIdList);
        foreach ($skioIdList as $skioIdItem){
            $SkitInfoVO     = $SkitInfoVOList[$skioIdItem]??null;
            if($SkitInfoVO !== null) $skitInfoVOListNew[] = $SkitInfoVO;
        }
        $SkitTplRmdVO->setSkitInfoList($skitInfoVOListNew);
        $SkitTplRmdVO->setDefault(intval($info['tprd_default']));
        $SkitTplRmdVO->setCreateTime(intval($info['tprd_create_time']));
        $SkitTplRmdVO->setUpdateTime(intval($info['tprd_update_time']));
        $SkitTplRmdVO->setPlatform(PlatformEnum::parseValue($info['tprd_platform']));
        return $SkitTplRmdVO;
    }

    /**
     * @param array $setData
     * @return int
     * skitTplRmdAdd
     */
    public function skitTplRmdAdd(array $setData):int
    {
        if(count($setData) < 1) return 0;
        $setString      = '';
        $isSetDefault   = false;
        $platform       = 0;
        foreach ($setData as $key => $val){
            switch ($key){
                case SkitTplRmdAddDTO::_skioIdList:
                    $skitInfoList   = SkitInfoCtl::tag()->getSkitInfoSrcBatch($val);
                    $skioIdList     = array_map('intval', array_column($skitInfoList, 'skio_id'));
                    $skioIdList     = array_values(array_intersect($val, $skioIdList));
                    $skioIdJson     = CommJson::encodeArray($skioIdList);
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'skio_ids=\''.$this->DbAuto->getRealEscapeString($skioIdJson).'\'';
                    break;
                case SkitTplRmdAddDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'tprd_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case SkitTplRmdAddDTO::_default:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'tprd_default='.intval($val);
                    if(intval($val) == YesOrNoEnum::YES_OR_NO_YES) $isSetDefault = true; // 设置默认
                    break;
                case SkitTplRmdAddDTO::_platform:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'tprd_platform='.intval($val);
                    $platform       = intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1) return 0;
        $currTime   = CommTime::getTimeStamp(0);
        $isFail     = false;
        $sql        = 'INSERT INTO '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').' SET '.$setString.', tprd_delete=0, tprd_create_time='.$currTime.', tprd_update_time='.$currTime;
        $tprdId     = $this->DbAuto->getDataId($sql, $isFail);
        if($isFail || $tprdId < 1) return 0;
        if($isSetDefault) $this->skitTplRmdDefaultUpdate($tprdId, $platform);
        return $tprdId;
    }

    /**
     * @param int $tprdId
     * @param array $setData
     * @param array $tplRmdSrc
     * @return bool
     * skitTplRmdEdit
     */
    public function skitTplRmdEdit(int $tprdId, array $setData, array $tplRmdSrc):bool
    {
        if($tprdId < 1 || count($setData) < 1 || !isset($tplRmdSrc['tprd_id'])) return false;
        $setString      = '';
        $isSetDefault   = false;
        $platform       = intval($tplRmdSrc['tprd_platform']);
        foreach ($setData as $key => $val){
            switch ($key){
                case SkitTplRmdEditDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'tprd_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case SkitTplRmdEditDTO::_skioIdList:
                    $skitInfoList   = SkitInfoCtl::tag()->getSkitInfoSrcBatch($val);
                    $skioIdList     = array_map('intval', array_column($skitInfoList, 'skio_id'));
                    $skioIdList     = array_values(array_intersect($val, $skioIdList));
                    $skioIdJson     = CommJson::encodeArray($skioIdList);
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'skio_ids=\''.$this->DbAuto->getRealEscapeString($skioIdJson).'\'';
                    break;
                case SkitTplRmdEditDTO::_default:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'tprd_default='.intval($val);
                    if(intval($val) == YesOrNoEnum::YES_OR_NO_YES) $isSetDefault = true; // 设置默认
                    break;
                case SkitTplRmdEditDTO::_platform:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'tprd_platform='.intval($val);
                    $platform       = intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1) return false;
        $isFail     = false;
        $currTime   = CommTime::getTimeStamp(0);
        $sql        = 'UPDATE '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').' SET '.$setString.', tprd_update_time='.$currTime.' WHERE tprd_id='.$tprdId.' AND tprd_delete=0';
        if($this->DbAuto->getDataNum($sql, $isFail) < 1 || $isFail) return false;
        if($isSetDefault) $this->skitTplRmdDefaultUpdate($tprdId, $platform);
        return true;
    }

    /**
     * @param int $tprdIdDefault
     * @param int $platform
     * @return bool
     * skitTplRmdDefaultUpdate
     */
    public function skitTplRmdDefaultUpdate(int $tprdIdDefault, int $platform):bool
    {
        if($tprdIdDefault < 1 || !in_array($platform, [0, 1, 2])) return false;
        $currTime   = CommTime::getTimeStamp();
        $isFail     = false;
        $resNum     = $this->DbAuto->getDataNum('UPDATE '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').' SET tprd_default=0, tprd_update_time='.$currTime.' WHERE tprd_id!='.$tprdIdDefault.' AND tprd_platform='.$platform.' AND tprd_delete=0', $isFail);
        if($isFail || $resNum < 1) return false;
        return true;
    }

    /**
     * @param int $tprdId
     * @return bool
     * skitTplRmdDel
     */
    public function skitTplRmdDel(int $tprdId):bool
    {
        if($tprdId < 1) return false;
        $isFail     = false;
        $currTime   = CommTime::getTimeStamp();
        $resNum     = $this->DbAuto->getDataNum('UPDATE '.$this->DbAuto->getTableNameAll('tpl_rmd_conf').' SET tprd_delete=1, tprd_update_time='.$currTime.' WHERE tprd_id='.$tprdId.' AND tprd_delete=0', $isFail);
        if($isFail || $resNum < 1) return false;
        return true;
    }
}